package PictureWork;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class PictureDeal
{
    JFrame frame = new JFrame("飞机设备分配图");
	private JPanel imagePanel;
	private ImageIcon background;
	private int upTaskRectNum;
	private int zoneNum[] =new int[8];
	private int posZone[][] = new int[8][2];
	private int posTastRect[][] = new int[2][2];
	private ArrayList HardwareAndTaskPos=new ArrayList();
	private int hardwareInfo[] = new int[14];
	private int softwareInfo[] = new int[58];
	private int taskNum[] = new int[14];
	
	public PictureDeal()
	{
		initialHardwareInfo();
		initialSoftwareInfo();
		initialZone();
		initialTastRect();
		drawSoftwarePic();
		drawHardwarePic();
		showDrawLine();
		drawPlanePicture("plane",170,230);

		frame.setSize(1370, 735);
		frame.setResizable(false);
		frame.setVisible(true);
		
	}
	
	public void initialHardwareInfo()
	{
		//读入硬件任务信息，解析每个位置
	       String fileName = "file/hardwareInfo.txt";
	       int locations = 7;
	       int devices = 14;
	       try
	       {
	       		FileInputStream input = new FileInputStream(fileName);
	       		int[] hardware = new int[locations * devices];
	       		Scanner  in = new Scanner(input);
	       		//后代读入硬件原始矩阵信息
	       		for(int i = 0;i< locations * devices ;i++){
	       		hardware[i] = in.nextInt();
	       	}
	       	//获取每一个硬件向量信息
	       	int[][] assignment = new int [devices][locations];
	       	for(int j = 0; j < devices; j++)
	       	{
	       		for(int k = 0; k < locations; k++)
	       		{
	       			assignment[j][k] = hardware[k*devices+j];
	       		}
	       	}
	       	//根据硬件向量信息进行解码，确定硬件编号和放置区域
	       	for(int j = 0; j < devices; j++)
	       	{
	       		for(int k = 0; k < locations; k++)
	       		{
	       			if(assignment[j][k] == 1)
	       			{
	       				hardwareInfo[j] = k+1;
	       			}
	       		}
	       	}
	       	
	       }
	       catch(Exception e)
	       {
	       		e.printStackTrace();
	       }	
	 
	}
	
	public void initialSoftwareInfo()
	{
		
		//读入软件任务信息、解析位置信息和初始化每个任务框数量
	    String fileName = "file/softwareInfo.txt";
	    int locations = 14;
	    int devices = 58;
	    try
	    {
	       	FileInputStream input = new FileInputStream(fileName);
	       	int[] software = new int[locations * devices];
	       	Scanner  in = new Scanner(input);
	       	//后代读入硬件原始矩阵信息
	       	for(int i = 0;i< locations * devices ;i++)
	       	{
	       		software[i] = in.nextInt();
	       	}
	       	//获取每一个硬件向量信息
	       	int[][] assignment = new int [devices][locations];
	       	for(int j = 0; j < devices; j++)
	       	{
	       		for(int k = 0; k < locations; k++)
	       		{
	       			assignment[j][k] = software[k*devices+j];
	       		}
	       	}
	       	//根据硬件向量信息进行解码，确定硬件编号和放置区域
	       	for(int j = 0; j < devices; j++)
	       	{
	       		for(int k = 0; k < locations; k++)
	       		{
	       			if(assignment[j][k] == 1)
	       			{
	       				softwareInfo[j] = k+1;
	       			}
	       		}
	       	}
	    }
	    catch(Exception e)
	    {
	       	e.printStackTrace();
	    }	
	    for(int i = 0;i < taskNum.length;i++)
	    {
	    	   taskNum[i] = 0;
	    }
	}
	
	public void initialZone()
	{
		//飞机各区域放置第一个 硬件设备坐标设置
		//存储当前 区域硬件设备个数
		for(int i = 1;i < 8;i++)
		{
			zoneNum[i] = 0;
		}
		//存储当前每个区域左上角坐标
		posZone[1][0] = 305;
		posZone[1][1] = 250;
		posZone[2][0] = 305;
		posZone[2][1] = 360;
		posZone[3][0] = 470;
		posZone[3][1] = 285;
		posZone[4][0] = 755;
		posZone[4][1] = 250;
		posZone[5][0] = 755;
		posZone[5][1] = 360;
		posZone[6][0] = 915;
		posZone[6][1] = 250;
		posZone[7][0] = 915;
		posZone[7][1] = 360;
	}
	
	public void initialTastRect()
	{
		//初始化上方第一个任务框参考坐标点
		posTastRect[0][0] = 30;
		posTastRect[0][1] = 5;
		//初始化下方第一个任务框参考坐标点
		posTastRect[1][0] = 30;
		posTastRect[1][1] = 600;
		upTaskRectNum = hardwareInfo.length - (hardwareInfo.length / 2); //确定上方框数量
	}
	
	public void drawHardwarePic()
	{
		//在飞机各区域画出硬件分配图片
		int cpm1 = 2;
		int cpm2 = 4;
		int rdc1 = 9;
		int rdc2 = 14;
		int i = 0;
		for (;i < cpm1;i++) 
		{
			zoneNum[hardwareInfo[i]]++;		//计算每个区域硬件设备数
			switch(hardwareInfo[i])
			{
				//根据所选区域调用相应函数进行画图
				case 1:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 2:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 3:
					planeZone3("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 4:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 5:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 6:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				default:
					planeOtherZone("cc_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
			}
		}
		for (;i < cpm2;i++) 
		{
			zoneNum[hardwareInfo[i]]++;		//计算每个区域硬件设备数
			switch(hardwareInfo[i])
			{
				//根据所选区域调用相应函数进行画图
				case 1:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 2:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 3:
					planeZone3("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 4:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 5:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 6:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				default:
					planeOtherZone("cc_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
			}
		}
		for (;i < rdc1;i++)
		{
			zoneNum[hardwareInfo[i]]++;		//计算每个区域硬件设备数
			switch(hardwareInfo[i])
			{
				//根据所选区域调用相应函数进行画图
				case 1:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 2:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 3:
					planeZone3("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 4:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 5:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 6:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				default:
					planeOtherZone("rio_type_1",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
			}
		}
		for (;i < rdc2;i++) 
		{
			zoneNum[hardwareInfo[i]]++;		//计算每个区域硬件设备数
			switch(hardwareInfo[i])
			{
				//根据所选区域调用相应函数进行画图
				case 1:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 2:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 3:
					planeZone3("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 4:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 5:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				case 6:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
					break;
				default:
					planeOtherZone("rio_type_2",i,hardwareInfo[i],zoneNum[hardwareInfo[i]]-1);
			}
		}
	}
	
	public void drawSoftwarePic()
	{
		int softwareA = 22;
		int softwareB = 38;
		int softwareC = 52;
		int softwareD = 58;
		int softwareCopyA = softwareA / 2;
		int softwareCopyB = (softwareB-softwareA) / 2;
		softwareCopyB = softwareCopyB + softwareA;
		int softwareCopyC = (softwareC - softwareB) / 2;
		softwareCopyC = softwareCopyC + softwareB;
		int softwareCopyD = (softwareD - softwareC) / 2;
		softwareCopyD = softwareCopyD + softwareC;
		int i=0;
		
		for(int j=0;i < softwareCopyA;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"a");
			taskNum[softwareInfo[i]-1]++;
		}
		for(int j=0;i < softwareA;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"a_copy");
			taskNum[softwareInfo[i]-1]++;
		}
		
		for(int j=0;i < softwareCopyB;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"b");
			taskNum[softwareInfo[i]-1]++;
		}
		for(int j=0;i < softwareB;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"b_copy");
			taskNum[softwareInfo[i]-1]++;
		}
		
		for(int j=0;i < softwareCopyC;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"c");
			taskNum[softwareInfo[i]-1]++;
		}
		for(int j=0;i < softwareC;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"c_copy");
			taskNum[softwareInfo[i]-1]++;
		}
		
		for(int j=0;i < softwareCopyD;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"d");
			taskNum[softwareInfo[i]-1]++;
		}
		for(int j=0;i < softwareD;i++,j++)
		{
			calTaskPos(j,softwareInfo[i]-1,"d_copy");
			taskNum[softwareInfo[i]-1]++;
		}
		
//		for(;i < softwareA;i++){
//			calTaskPos(i,softwareInfo[i]-1,"a");
//			taskNum[softwareInfo[i]-1]++;
//		}
//		for(;i < softwareB;i++){
//			calTaskPos(i,softwareInfo[i]-1,"b");
//			taskNum[softwareInfo[i]-1]++;
//		}
//		for(;i < softwareC;i++){
//			calTaskPos(i,softwareInfo[i]-1,"c");
//			taskNum[softwareInfo[i]-1]++;
//		}
//		for(;i < softwareD;i++){
//			calTaskPos(i,softwareInfo[i]-1,"d");
//			taskNum[softwareInfo[i]-1]++;
//		}
		
	}
	
	public void drawPlanePicture(String imageName,int posX,int posY)
	{
		
		//设置飞机机身与飞机硬件7个区域背景图片
		background = new ImageIcon("images/"+imageName+".png");// 背景图片
		JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面
		// 把标签的大小位置设置为图片刚好填充整个面板
		label.setBounds(posX, posY, background.getIconWidth(),240);
		// 把内容窗格转化为JPanel，否则不能用方法setOpaque()来使内容窗格透明
		imagePanel = (JPanel) frame.getContentPane();
		imagePanel.setOpaque(false);
		// 内容窗格默认的布局管理器为BorderLayout
		imagePanel.setLayout(new FlowLayout());
		frame.getLayeredPane().setLayout(null);
		// 把背景图片添加到分层窗格的最底层作为背景
		frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
	}
	
	public void drawEquipPicture(String imageName,int posX,int posY)
	{
		background = new ImageIcon("images/"+imageName+".png");// 背景图片
		JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面
		// 把标签的大小位置设置为图片刚好填充整个面板
		label.setBounds(posX, posY, background.getIconWidth(),background.getIconHeight());
		// 把内容窗格转化为JPanel，否则不能用方法setOpaque()来使内容窗格透明
		imagePanel = (JPanel) frame.getContentPane();
		imagePanel.setOpaque(false);
		// 内容窗格默认的布局管理器为BorderLayout
		imagePanel.setLayout(new FlowLayout());
		frame.getLayeredPane().setLayout(null);
		// 把背景图片添加到分层窗格的最底层作为背景
		frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
	}
	
	public void drawSoftWarePicture(String imageName,int posX,int posY)
	{
		  background = new ImageIcon("images/"+imageName+".png");// 背景图片
		  JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面
		  // 把标签的大小位置设置为图片刚好填充整个面板
		  label.setBounds(posX, posY, background.getIconWidth(),background.getIconHeight());
		  // 把内容窗格转化为JPanel，否则不能用方法setOpaque()来使内容窗格透明
		  imagePanel = (JPanel) frame.getContentPane();
		  
		  imagePanel.setOpaque(false);
		  // 内容窗格默认的布局管理器为BorderLayout
		  imagePanel.setLayout(new FlowLayout());

		  frame.getLayeredPane().setLayout(null);
		  // 把背景图片添加到分层窗格的最底层作为背景
		  frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
	}
	
	public void drawNumLabel(Integer num,int x,int y)
	{
		//在指定位置显示一个指定数字label
		JLabel label = new JLabel(num.toString());
		label.setBounds(x, y, 60,40);
		label.setFont(new java.awt.Font("Dialog",1,24));
		frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
	}
	
	public void calSoftware(int softwareOrder,int taskOrder,int x,int y,String imageName)
	{
		int numX = (taskNum[taskOrder] % 5);
		int numY = (taskNum[taskOrder] / 5);
		int imageX = x + numX * 34;
		int imageY = y + numY * 34;
		drawNumLabel(softwareOrder+1,imageX+3,imageY-5);
		drawSoftWarePicture(imageName,imageX,imageY);
	}
	
	public void calTaskPos(int softwareOrder,int i,String imageName)
	{
		//根据软件位置信息选中任务框
		if(i < upTaskRectNum)
		{
			getTastUpPos(softwareOrder,i,i,imageName);
		}
		else
		{
			getTastDownPos(softwareOrder,i - upTaskRectNum,i,imageName);
		}
	}
	
	public void getTastUpPos(int softwareOrder,int i,int taskOrder,String imageName)
	{
		//创建上任务框
		int x = (i % 7);
		int y = (i / 7);
		int taskRectX = posTastRect[0][0] + x * 190;
		int taskRectY = posTastRect[0][1] + y * 110;
		calSoftware(softwareOrder,taskOrder,taskRectX,taskRectY,imageName);
	}
	
	public void getTastDownPos(int softwareOrder,int i,int taskOrder,String imageName)
	{
		//创建下任务框
		int x = (i % 7);
		int y = (i / 7);
		int taskRectX = posTastRect[1][0] + x * 190;
		int taskRectY = posTastRect[1][1] - y * 110;
		calSoftware(softwareOrder,taskOrder,taskRectX,taskRectY,imageName);
	}
	
	public void showDrawLine()
	{
		frame.setContentPane(new JPanel()
		{
			@Override
			public void paint(Graphics g)
			{
				super.paint(g);
				g.setColor(Color.red);
				int x1,y1,x2,y2;
				for(int i = 0;i < HardwareAndTaskPos.size();i++)
				{
					HashMap<String,Integer> pos = new HashMap<String,Integer>();
					pos = (HashMap<String,Integer>) HardwareAndTaskPos.get(i);
					x1 = pos.get("x1");
					y1 = pos.get("y1");
					x2 = pos.get("x2");
					y2 = pos.get("y2");
					g.drawLine(x1,y1,x2,y2);
				}
			}
		});
	}
	
	public void calDrawLinePos(int x1,int y1,int x2,int y2)
	{
		//根据两点画直线
		HashMap<String,Integer> pos = new HashMap<String,Integer>();
		pos.put("x1", x1);
		pos.put("y1", y1);
		pos.put("x2", x2);
		pos.put("y2", y2);
		HardwareAndTaskPos.add(pos);
	}
	
	public void planeOtherZone(String imageName,int i,int zone,int zoneNum)
	{
		//画出非飞机机身非第三区域硬件设备图
		int x = (zoneNum % 3);
		int y = (zoneNum / 3);
		int imageX = posZone[zone][0] + x * 45;
		int imageY = posZone[zone][1] + y * 50;
		drawNumLabel(i+1,imageX+10,imageY+20);
		drawEquipPicture(imageName,imageX,imageY);
		createTastRect(i,upTaskRectNum,imageX,imageY);
	}
	
	public void planeZone3(String imageName,int i,int zone,int zoneNum)
	{
		//画出飞机机身第三区域硬件设备图
		int x = (zoneNum % 5);
		int y = (zoneNum / 5);
		int imageX = posZone[zone][0] + x * 45;
		int imageY = posZone[zone][1] + y * 50;
		drawNumLabel(i+1,imageX+10,imageY+20);
		drawEquipPicture(imageName,imageX,imageY);
		createTastRect(i,upTaskRectNum,imageX,imageY);
	}
	
	public void createTastRect(int i,int upTaskRectNum,int hardwareX,int hardwareY)
	{
		//根据第几个设备匹配任务框是否在半数内，在则创建上任务框，否则创建下任务框
		if(i < upTaskRectNum)
		{
			createTastUpRect(i,hardwareX,hardwareY);
		}
		else
		{
			createTastDownRect(i - upTaskRectNum,hardwareX,hardwareY);
		}
	}
	
	public void createTastUpRect(int i,int hardwareX,int hardwareY)
	{
		//创建上任务框
		int x = (i % 7);
		int y = (i / 7);
		int imageX = posTastRect[0][0] + x * 190;
		int imageY = posTastRect[0][1] + y * 110;
		drawTaskPicture(imageX,imageY);
		background = new ImageIcon("images/rio_type_1.png");
		hardwareX = hardwareX + (background.getIconWidth() / 2);
		int taskX = imageX + 85;
		int taskY = imageY + 100;
		calDrawLinePos(hardwareX,hardwareY,taskX,taskY);
	}
	
	public void createTastDownRect(int i,int hardwareX,int hardwareY)
	{
		//创建下任务框
		int x = (i % 7);
		int y = (i / 7);
		int imageX = posTastRect[1][0] + x * 190;
		int imageY = posTastRect[1][1] - y * 110;
		drawTaskPicture(imageX,imageY);
		background = new ImageIcon("images/rio_type_1.png");
		hardwareX = hardwareX + (background.getIconWidth() / 2);
		hardwareY = hardwareY + background.getIconHeight();
		int taskX = imageX + 85;
		int taskY = imageY;
		
		calDrawLinePos(hardwareX,hardwareY,taskX,taskY);
	}

	void drawTaskPicture(int posX,int posY)
	{
		  background = new ImageIcon("images/task.png");// 背景图片
		  JLabel label = new JLabel(background);// 把背景图片显示在一个标签里面
		  // 把标签的大小位置设置为图片刚好填充整个面板
		  label.setBounds(posX, posY, 170,100);
		  // 把内容窗格转化为JPanel，否则不能用方法setOpaque()来使内容窗格透明
		  imagePanel = (JPanel) frame.getContentPane();
		  //contentPane = frame.getContentPane(); 
		  imagePanel.setOpaque(false);
		  // 内容窗格默认的布局管理器为BorderLayout
		  imagePanel.setLayout(new FlowLayout());
		  frame.getLayeredPane().setLayout(null);
		  // 把背景图片添加到分层窗格的最底层作为背景
		  frame.getLayeredPane().add(label, new Integer(Integer.MIN_VALUE));
	}
	
   public static void main(String[] args)
   {
       //自动生成飞机装配图片
       new PictureDeal();
       
   }
	
}
